package com.es.client.elasticesearch;


import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.concurrent.ExecutionException;

import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse;
import org.elasticsearch.action.admin.indices.exists.types.TypesExistsResponse;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.IndicesAdminClient;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.transport.client.PreBuiltTransportClient;


public class ESClient {
	private static String CLUSTER_NAME = "elasticsearch";
	private static String HOST_IP = "119.23.250.150";
	private static int PORT = 9300;
	private Client client;
	private ESClient(){
		this.client = createTransportClient();
	}
	private static class Holder{
		private static final ESClient INSTANCE = new ESClient();
	}
	
	public static ESClient getEsClient(){
		return Holder.INSTANCE;
	}
	
	
	
	/**
	 * 创建TransportClient
	 * @return
	 */
	@SuppressWarnings({ "unchecked", "resource" })
	private Client createTransportClient() {
		Settings settings = Settings.builder().put("cluster.name",CLUSTER_NAME)
				.build();
		InetSocketAddress address = new InetSocketAddress(HOST_IP, PORT);
		TransportAddress transportAddress = new TransportAddress(address);
		TransportClient client = new PreBuiltTransportClient(settings)
				.addTransportAddress(transportAddress);
		return client;
	}
	
	
	/**
	 * 生成索引文档
	 * @param index
	 * @param type
	 * @param json
	 * @throws IOException
	 * @throws ExecutionException 
	 * @throws InterruptedException 
	 */
	public void createDoc(String index,String type, String id, String json) throws IOException, InterruptedException, ExecutionException {		
		XContentParser parser = XContentFactory.xContent(XContentType.JSON). createParser(NamedXContentRegistry.EMPTY, json);
		//GetResponse getResponse = client.prepareGet(index, type, id).get();
		//IndexResponse response = client.prepareIndex(index, type, id).setSource(parser.map()).execute().actionGet();
		//printIndexInfo(response);
		IndexRequest request = new IndexRequest(index, type, id);
		
		GetResponse getResponse = client.prepareGet(index, type, id).get();
		if (!getResponse.isExists()) {
			request.source(parser.map());
		}
		
		
		UpdateRequest updateRequest = new UpdateRequest(index, type, id).
				doc(parser.map()).upsert(request);
		UpdateResponse response = client.update(updateRequest).actionGet();
		printIndexInfo(response);
	}


	/**
	 * 打印索引信息
	 * @param response
	 */
	private void printIndexInfo(UpdateResponse response) {
		System.out.println("****************index ***********************");
		// Index name
		String _index = response.getIndex();
		// Type name
		String _type = response.getType();
		// Document ID (generated or not)
		String _id = response.getId();
		// Version (if it's the first time you index this document, you will get: 1)
		long _version = response.getVersion();
		System.out.println(_index+","+_type+","+_id+","+_version);
	}
	
	/**
	 * 创建索引
	 * @param index
	 * @param type
	 * @param builder
	 * @return
	 * @throws Exception
	 */
    public boolean createIndex(String index,String type,XContentBuilder mapping,XContentBuilder settingBuilder)throws Exception{
    	IndicesAdminClient adminClient = client.admin().indices();
    	IndicesExistsResponse indexExistsResponse = adminClient.prepareExists(index).get();
    	if (indexExistsResponse.isExists()) {//判断索引是否存在
    		TypesExistsResponse typeExistsResponse = adminClient.prepareTypesExists(index).setTypes(type).get();
    		if (typeExistsResponse.isExists()) {//判断type是否存在
				return true;
			}
		}
    	
    	CreateIndexRequestBuilder builder = adminClient.prepareCreate(index);
    	builder.setSettings(settingBuilder);//设置setting
    	CreateIndexResponse response =  builder.get();
    	if (response.isAcknowledged()) {
        	PutMappingResponse mappingResponse = adminClient.preparePutMapping(index).setType(type).setSource(mapping).get();
        	return mappingResponse.isAcknowledged();
		}
      return false;
    }
}
